#include "stdafx.h"
#include <boost/test/auto_unit_test.hpp>
#include "detail/bmock_test_control_tools.hpp"
#include <boost/lexical_cast.hpp>

namespace bmock {
	void test_control_tools::error(const std::string &msg,const location &loc,const bool fail,const bool except) const {
		boost::test_toolbox::tt_detail::check_impl( false 
			,boost::unit_test::lazy_ostream::instance() << msg
			,loc.first
			,loc.second
			,fail?boost::test_toolbox::tt_detail::REQUIRE:boost::test_toolbox::tt_detail::CHECK
			,boost::test_toolbox::tt_detail::CHECK_MSG,0);
		if(!fail&&except) throw loc;
	}

	void test_control_tools::abort(const location &loc) const {
		boost::test_toolbox::tt_detail::check_impl( false 
			,boost::unit_test::lazy_ostream::instance()
			,loc.first
			,loc.second
			,boost::test_toolbox::tt_detail::REQUIRE
			,boost::test_toolbox::tt_detail::CHECK_MSG,0);
	}

	bool test_control_tools::warn(const std::string &msg,const location & loc) const{		
		boost::test_toolbox::tt_detail::check_impl(false
			,boost::unit_test::lazy_ostream::instance() << msg 
			,loc.first
			,loc.second
			,boost::test_toolbox::tt_detail::WARN
			,boost::test_toolbox::tt_detail::CHECK_MSG
			,0);
		
		return true;
	}

	bool test_control_tools::check_equal(const std::string &exp,const std::string &act,const std::string &msg,const location &loc) const {
		boost::test_tools::predicate_result r(exp == act);
		r.message() << '[' << exp << " != " << act << ']';
		boost::test_toolbox::tt_detail::check_impl(r 
			,boost::unit_test::lazy_ostream::instance() << msg
			,loc.first
			,loc.second
			,boost::test_toolbox::tt_detail::CHECK
			,boost::test_toolbox::tt_detail::CHECK_PRED
			,0);
		return !r;
	}

	void test_control_tools::require_equal(const size_t exp,const size_t act,const std::string &msg,const location &loc) const {
		boost::test_tools::predicate_result r(exp == act);
		r.message() << '[' << exp << " != " << act << ']';
		boost::test_toolbox::tt_detail::check_impl(r
			,boost::unit_test::lazy_ostream::instance() << msg 
			,loc.first
			,loc.second
			,boost::test_toolbox::tt_detail::REQUIRE
			,boost::test_toolbox::tt_detail::CHECK_PRED
			,0);
		if(!r) throw loc;
	}
	bool test_control_tools::warn_not_equal(const size_t exp,const size_t act,const std::string &msg,const location & loc) const{
		boost::test_tools::predicate_result r(exp == act);
		r.message() << '[' << exp << " != " << act << ']';
		boost::test_toolbox::tt_detail::check_impl(r
			,boost::unit_test::lazy_ostream::instance() << msg 
			,loc.first
			,loc.second
			,boost::test_toolbox::tt_detail::WARN
			,boost::test_toolbox::tt_detail::CHECK_MSG
			,0);
		return !r;
	}

	bool test_control_tools::check_less_or_equal(const size_t exp,const size_t act,const std::string &msg,const location &loc) const {
		boost::test_tools::predicate_result r(exp <= act);
		r.message() << '[' << exp << " > " << act << ']';
		boost::test_toolbox::tt_detail::check_impl(r 
			,boost::unit_test::lazy_ostream::instance() << msg
			,loc.first
			,loc.second
			,boost::test_toolbox::tt_detail::CHECK
			,boost::test_toolbox::tt_detail::CHECK_PRED
			,0);
		return !r;
	}

	bool test_control_tools::check_ptr(bool null_expected,const bool null_supplied,const std::string &msg,const location &loc) const {
		const bool r1 = null_expected && null_supplied;
		const bool r2 = !null_expected && !null_supplied;
		boost::test_tools::predicate_result r(r1 || r2);
		r.message() << '[' << null_expected << "," << null_supplied << ']';
		boost::test_toolbox::tt_detail::check_impl(r
			,boost::unit_test::lazy_ostream::instance() << msg
			,loc.first
			,loc.second
			,boost::test_toolbox::tt_detail::CHECK
			,boost::test_toolbox::tt_detail::CHECK_PRED
			,0);
		return !r;
	}

	bool test_control_tools::check_equal_no_msg(const std::string &exp,const std::string &act,const location &) const {
		boost::test_tools::predicate_result r(exp == act);
		return !r;
	}

	bool test_control_tools::check_ptr_no_msg(bool null_expected,const bool null_supplied,const location &) const {
		const bool r1 = null_expected && null_supplied;
		const bool r2 = !null_expected && !null_supplied;
		boost::test_tools::predicate_result r(r1 || r2);
		return !r;
	}
}